package repository

import entity.SignUpActivity
import org.hibernate.criterion.Restrictions

class SignUpActivityRepositoryImpl : SignUpActivityRepository {
    override fun findByUserId(uId: Int): List<SignUpActivity> {
        return executeTransaction { session ->
            val criteria = session.createCriteria(SignUpActivity::class.java)
            criteria.add(Restrictions.eq("userId", uId))
            criteria.list().map { it as SignUpActivity }
        }
    }

    override fun findByUserId(uId: Int, pageable: Pageable): Page<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            cr.add(Restrictions.eq("userId", uId))
            cr.sortBy(pageable)
            cr.setFirstResult(pageable.pageSize * pageable.pageSize)
            cr.setMaxResults(pageable.pageSize)
            val list = cr.list().map { it as SignUpActivity }
            Page(
                content = list,
                pageable = pageable,
                totalElements = list.size.toLong()
            )
        }
    }

    override fun findByActivityId(aId: Int): List<SignUpActivity> {
        return executeTransaction { session ->
            val criteria = session.createCriteria(SignUpActivity::class.java)
            criteria.add(Restrictions.eq("activityId", aId))
            criteria.list().map { it as SignUpActivity }
        }
    }

    override fun findByActivityId(aId: Int, pageable: Pageable): Page<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            cr.add(Restrictions.eq("activityId", aId))
            cr.sortBy(pageable)
            cr.setFirstResult(pageable.pageSize * pageable.pageSize)
            cr.setMaxResults(pageable.pageSize)
            val list = cr.list().map { it as SignUpActivity }
            Page(
                content = list,
                pageable = pageable,
                totalElements = list.size.toLong()
            )
        }
    }

    override fun findByActivityIdAndUserId(aId: Int, uId: Int): SignUpActivity {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("activityId", aId)
            val crChecked = Restrictions.eq("userId", uId)
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)

            cr.uniqueResult() as SignUpActivity
        }
    }

    override fun findByPassedTrue(): List<SignUpActivity> {
        return executeTransaction { session ->
            val criteria = session.createCriteria(SignUpActivity::class.java)
            criteria.add(Restrictions.eq("passed", true))
            criteria.list().map { it as SignUpActivity }
        }
    }

    override fun findByPassedTrue(pageable: Pageable): Page<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            cr.add(Restrictions.eq("passed", true))
            cr.sortBy(pageable)
            cr.setFirstResult(pageable.pageSize * pageable.pageSize)
            cr.setMaxResults(pageable.pageSize)
            val list = cr.list().map { it as SignUpActivity }
            Page(
                content = list,
                pageable = pageable,
                totalElements = list.size.toLong()
            )
        }
    }

    override fun findByPassedFalse(): List<SignUpActivity> {
        return executeTransaction { session ->
            val criteria = session.createCriteria(SignUpActivity::class.java)
            criteria.add(Restrictions.eq("passed", false))
            criteria.list().map { it as SignUpActivity }
        }
    }

    override fun findByPassedFalse(pageable: Pageable): Page<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            cr.add(Restrictions.eq("passed", false))
            cr.sortBy(pageable)
            cr.setFirstResult(pageable.pageSize * pageable.pageSize)
            cr.setMaxResults(pageable.pageSize)
            val list = cr.list().map { it as SignUpActivity }
            Page(
                content = list,
                pageable = pageable,
                totalElements = list.size.toLong()
            )
        }
    }

    override fun findByUserIdAndPassedTrue(userId: Int): List<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("userId", userId)
            val crChecked = Restrictions.eq("passed", true)
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.list().map { it as SignUpActivity }
        }
    }

    override fun findByUserIdAndPassedTrue(userId: Int, pageable: Pageable): Page<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("userId", userId)
            val crChecked = Restrictions.eq("passed", true)
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.sortBy(pageable)
            cr.setFirstResult(pageable.pageSize * pageable.pageSize)
            cr.setMaxResults(pageable.pageSize)
            val list = cr.list().map { it as SignUpActivity }
            Page(
                content = list,
                pageable = pageable,
                totalElements = list.size.toLong()
            )
        }
    }

    override fun findByUserIdAndPassedFalse(userId: Int): List<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("userId", userId)
            val crChecked = Restrictions.eq("passed", false)
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.list().map { it as SignUpActivity }
        }
    }

    override fun findByUserIdAndPassedFalse(userId: Int, pageable: Pageable): Page<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("userId", userId)
            val crChecked = Restrictions.eq("passed", false)
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.sortBy(pageable)
            cr.setFirstResult(pageable.pageSize * pageable.pageSize)
            cr.setMaxResults(pageable.pageSize)
            val list = cr.list().map { it as SignUpActivity }
            Page(
                content = list,
                pageable = pageable,
                totalElements = list.size.toLong()
            )
        }
    }

    override fun findByUserIdAndPassedIsNull(userId: Int): List<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("userId", userId)
            val crChecked = Restrictions.isNull("passed")
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.list().map { it as SignUpActivity }
        }
    }

    override fun findByUserIdAndPassedIsNull(userId: Int, pageable: Pageable): Page<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("userId", userId)
            val crChecked = Restrictions.isNull("passed")
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.sortBy(pageable)
            cr.setFirstResult(pageable.pageSize * pageable.pageSize)
            cr.setMaxResults(pageable.pageSize)
            val list = cr.list().map { it as SignUpActivity }
            Page(
                content = list,
                pageable = pageable,
                totalElements = list.size.toLong()
            )
        }
    }

    override fun findByActivityIdAndPassedTrue(activityId: Int): List<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("activityId", activityId)
            val crChecked = Restrictions.eq("passed", true)
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.list().map { it as SignUpActivity }
        }
    }

    override fun findByActivityIdAndPassedTrue(activityId: Int, pageable: Pageable): Page<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("activityId", activityId)
            val crChecked = Restrictions.eq("passed", true)
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.sortBy(pageable)
            cr.setFirstResult(pageable.pageSize * pageable.pageSize)
            cr.setMaxResults(pageable.pageSize)
            val list = cr.list().map { it as SignUpActivity }
            Page(
                content = list,
                pageable = pageable,
                totalElements = list.size.toLong()
            )
        }
    }

    override fun findByActivityIdAndPassedFalse(activityId: Int): List<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("activityId", activityId)
            val crChecked = Restrictions.eq("passed", false)
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.list().map { it as SignUpActivity }
        }
    }

    override fun findByActivityIdAndPassedFalse(activityId: Int, pageable: Pageable): Page<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("activityId", activityId)
            val crChecked = Restrictions.eq("passed", false)
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.sortBy(pageable)
            cr.setFirstResult(pageable.pageSize * pageable.pageSize)
            cr.setMaxResults(pageable.pageSize)
            val list = cr.list().map { it as SignUpActivity }
            Page(
                content = list,
                pageable = pageable,
                totalElements = list.size.toLong()
            )
        }
    }

    override fun findByActivityIdAndPassedIsNull(activityId: Int): List<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("activityId", activityId)
            val crChecked = Restrictions.isNull("passed")
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.list().map { it as SignUpActivity }
        }
    }

    override fun findByActivityIdAndPassedIsNull(activityId: Int, pageable: Pageable): Page<SignUpActivity> {
        return executeTransaction { session ->
            val cr = session.createCriteria(SignUpActivity::class.java)
            val crPublisher = Restrictions.eq("activityId", activityId)
            val crChecked = Restrictions.isNull("passed")
            val andExp = Restrictions.and(crPublisher, crChecked)
            cr.add(andExp)
            cr.sortBy(pageable)
            cr.setFirstResult(pageable.pageSize * pageable.pageSize)
            cr.setMaxResults(pageable.pageSize)
            val list = cr.list().map { it as SignUpActivity }
            Page(
                content = list,
                pageable = pageable,
                totalElements = list.size.toLong()
            )
        }
    }

    // Unnecessary, so return empty value
    override fun findByActivityIdAndSignFalse(activityId: Int): List<SignUpActivity> {
        return arrayListOf()
    }

    // Unnecessary, so return empty value
    override fun findByActivityIdAndSignFalse(activityId: Int, pageable: Pageable): Page<SignUpActivity> {
        return Page(arrayListOf(), pageable, 0)
    }

    // Unnecessary, so return empty value
    override fun findByActivityIdAndSignTrue(activityId: Int): List<SignUpActivity> {
        return arrayListOf()
    }

    // Unnecessary, so return empty value
    override fun findByActivityIdAndSignTrue(activityId: Int, pageable: Pageable): Page<SignUpActivity> {
        return Page(arrayListOf(), pageable, 0)
    }

    // Unnecessary, so return empty value
    override fun findByUserIdAndSignFalse(userId: Int): List<SignUpActivity> {
        return arrayListOf()
    }

    // Unnecessary, so return empty value
    override fun findByUserIdAndSignFalse(userId: Int, pageable: Pageable): Page<SignUpActivity> {
        return Page(arrayListOf(), pageable, 0)
    }

    // Unnecessary, so return empty value
    override fun findByUserIdAndSignTrue(userId: Int): List<SignUpActivity> {
        return arrayListOf()
    }

    // Unnecessary, so return empty value
    override fun findByUserIdAndSignTrue(userId: Int, pageable: Pageable): Page<SignUpActivity> {
        return Page(arrayListOf(), pageable, 0)
    }
}